using OpenTap.Plugins.Interfaces.Common;
using OpenTap.Plugins.Interfaces.SCPI;

namespace OpenTap.Plugins.Interfaces.PSU
{
    #region enums
    /// <summary>
    /// Module number for modular power supply.
    /// </summary>
    public enum EModule
    {
        Module1 = 1,
        Module2 = 2,
        Module3 = 3,
        Module4 = 4
    }


    public enum EView
    {
        Meter1 = 1,
        Meter4 = 4
    }

    /// <summary>
    /// Output relay state.
    /// </summary>
    public enum EPolarity
    {
        Normal, // Positive
        Reverse // Negative
    }

    #endregion

    public interface IPsu : IInstrument, IScpi
    {
        /// <summary>
        ///     Gets the module ID data. (As returned by the SCPI command *IDN?).
        /// </summary>
        /// <returns>Modulenumber, model, options, serialNumber</returns>
        string IdnModule(EModule moduleNumber, out int numberOfModules);

        /// <summary>
        ///     Measures current. Unit is ampere
        /// </summary>
        /// <returns>Measured current</returns>
        double MeasureCurrent(EModule module = EModule.Module1);

        /// <summary>
        ///     Measures voltage. Unit is voltage
        /// </summary>
        /// <returns>Measured voltage</returns>
        double MeasureVoltage(EModule module = EModule.Module1);

        /// <summary>
        ///     Sets the current limit to instrument.
        /// </summary>
        /// <param name="currentAmps">Current limit in ampere</param>
        /// <param name="module"></param>
        void SetCurrent(double currentAmps, EModule module = EModule.Module1);

        /// <summary>
        ///     Gets the current limit which is set to instrument.
        /// </summary>
        /// <returns>The defined current limit in ampere. NaN if not set yet.</returns>
        double GetCurrentLimit(EModule module = EModule.Module1);

        /// <summary>
        ///     Sets the current protection state to instrument.
        /// </summary>
        /// <param name="state">State to be set</param>
        /// <param name="module"></param>
        void SetCurrentProtectionState(EState state, EModule module = EModule.Module1);

        /// <summary>
        ///     Asks the current protection status from instrument.
        /// </summary>
        /// <returns>The current protection status</returns>
        EState GetCurrentProtectionStatus(EModule module = EModule.Module1);

        /// <summary>
        /// Reads the output state of the instrument.
        /// </summary>
        /// <returns>The output state.</returns>
        EState GetOutputState(EModule module = EModule.Module1);

        /// <summary>
        ///     Sets the output state to the instrument.
        /// </summary>
        /// <param name="state">The state to be set</param>
        /// <param name="module"></param>
        void SetOutputState(EState state, EModule module = EModule.Module1);

        /// <summary>
        ///     Resets any tripped protection from instrument.
        /// </summary>
        void ClearOutputProtection(EModule module = EModule.Module1);

        /// <summary>
        ///     Sets the output voltage.
        /// </summary>
        /// <param name="pVoltageVolts">The voltage to be set in volts</param>
        /// <param name="module"></param>
        void SetVoltage(double pVoltageVolts, EModule module = EModule.Module1);

        /// <summary>
        ///     Gets the voltage level that is set to instrument.
        /// </summary>
        /// <returns>The defined voltage limit in volts. NaN if not set</returns>
        double GetVoltageLevel(EModule module = EModule.Module1);

        /// <summary>
        /// Gets the voltage MAX level, what the instrument can supply.
        /// </summary>
        /// <returns>The voltage MAX level. NaN if not set</returns>
        double GetVoltageLevelMax(EModule module = EModule.Module1);

        /// <summary>
        /// Sets the output Over Voltage Protection Level.
        /// </summary>
        /// <param name="voltage">The voltage to be set in volts</param>
        /// <param name="module"></param>
        void SetOverVoltageLevel(double voltage, EModule module = EModule.Module1);

        /// <summary>
        /// Gets the Over Voltage Protection Level.
        /// </summary>
        /// <returns>The voltage level.</returns>
        double GetOverVoltageLevel(EModule module = EModule.Module1);

        /// <summary>
        /// Gets the Over Voltage Protection Level MAX value, which instrument support.
        /// </summary>
        /// <returns>The voltage level.</returns>
        double GetOverVoltageLevelMax(EModule module = EModule.Module1);

        /// <summary>
        /// Sets the output voltage polarity.
        /// </summary>
        /// <param name="polarity">Polarity set value</param>
        /// <param name="module"></param>
        void SetPolarity(EPolarity polarity, EModule module = EModule.Module1);

        /// <summary>
        ///     Asks the if DC input fault has been triggered and clears the flag status.
        /// </summary>
        /// <returns>The DC feed fault status</returns>
        EState GetDcFeedFaultStatus(EModule module = EModule.Module1);

        /// <summary>
        /// For modular PSU's. This function sets 1-channel or 4-channel meter view.
        /// </summary>
        /// <param name="view"> select between 1 and 4 slot view.</param>
        void SetMeterView(EView view);

        /// <summary>
        /// Function: Define Groups for Modular PSU's
        /// Purpose:  This function defines parallel outputs as group.
        /// Parameters:Channel list (@[channel] ,[channel],[channel],[channel])
        /// You can also specify a range of sequential channels as follows: [start_channel:[end_channel]
        /// </summary>
        /// <param name="channelList">list of channels</param>
        void ModularPower_DefineGroups(string channelList);

        /// <summary>
        /// This function deletes ALL defined groups from modular PSU
        /// </summary>
        void ModularPower_DeleteGroups();

        /// <summary>
        /// This function return channels that are grouped at modular PSU
        /// </summary>
        /// <returns>list of grouped channels</returns>
        string ModularPower_CatalogOfGroupedChannels();

        /// <summary>
        /// Run manufacturers self-test(*TST?) for instrument.
        /// </summary>
        /// <param name="message"> Message returned from test.</param>
        /// <returns>Result code: 0 = pass / other numbers are error/fails.</returns>
        int SelfTest(out string message);

        /// <summary>
        ///     Method to check if PSU has multiple modules or just one.
        /// </summary>
        /// <returns>true if PSU is modular, otherwise false</returns>
        bool IsModular();

        void Close(bool keepPowerOn);
    }
}